package com.itheima.service.impl;

import com.itheima.mapper.*;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.itheima.common.entity.PageResult;
import com.itheima.common.entity.QueryPageBean;
import com.itheima.common.utils.AliOssUtil;
import com.itheima.config.AliOssProperties;
import com.itheima.pojo.CheckGroup;
import com.itheima.pojo.Setmeal;
import com.itheima.service.SetmeaService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author Encounter
 * @date 2024/10/05 13:47<br/>
 */
@Service
@Slf4j
public class SetmealServiceImpl implements SetmeaService
    {
        @Autowired
        private SetmealMapper setmealMapper;
        @Autowired
        private CheckGroupMapper checkGroupMapper;
        @Autowired
        private SetmealCheckGroupMapper setmealCheckGroupMapper;
        //调用CheckGroupServiceImpl中定义的解析查询条件的方法
        @Autowired
        private CheckGroupServiceImpl checkGroupServiceImpl;
        @Autowired
        private AliOssUtil aliOssUtil;
        @Autowired
        private AliOssProperties aliOssProperties;
        @Value("${freemarker.out.path}")
        private String path;
        
        /**
         * 新增套餐
         *
         * @param setmeal 套餐
         */
        @Override
        @Transactional
        public void add(Setmeal setmeal, List<Integer> checkgroupIds)
            {
                //插入新套餐
                setmealMapper.insert(setmeal);
                
                //插入套餐关联的检查组
                insertSetmealCheckGroup(setmeal, checkgroupIds);
                
                //删除静态页面
                deleteStaticPages();
            }
        
        /**
         * 找到由id
         *
         * @param setmealId 套餐id
         * @return {@link Setmeal }
         */
        @Override
        public Setmeal findById(Integer setmealId)
            {
                //封装查询条件，查询条件为id
                Map<String, Object> map = new HashMap<>();
                map.put("setmealId", setmealId);
                
                //查询
                List<Setmeal> setmealList = setmealMapper.query(map);
                //id是唯一的，所以根据id查询只有一个数据，直接返回第一个数据即可
                Setmeal setmeal = setmealList.get(0);
                //查询套餐关联的检查组信息
                if (setmeal != null)
                    {
                        List<CheckGroup> checkGroupList = new ArrayList<>();
                        for (Integer checkGroupId : setmealCheckGroupMapper.findCheckGroupIdsBySetmealId(setmeal.getId()))
                            {
                                CheckGroup checkGroup = checkGroupMapper.getById(checkGroupId);
                                checkGroupList.add(checkGroup);
                            }
                        setmeal.setCheckGroups(checkGroupList);
                    }
                
                return setmeal;
            }
        
        /**
         * 编辑套餐
         *
         * @param setmeal 套餐
         */
        @Override
        @Transactional
        public void edit(Setmeal setmeal, List<Integer> checkGroupIds)
            {
                //修改套餐表
                setmealMapper.update(setmeal);
                
                //修改套餐表关联的检查组
                if (checkGroupIds != null && !checkGroupIds.isEmpty())
                    {
                        insertSetmealCheckGroup(setmeal, checkGroupIds);
                    }
                
                //删除静态页面
                deleteStaticPages();
            }
        
        /**
         * 动态分页查询
         *
         * @param queryPageBean 查询页面 Bean
         * @return {@link PageResult }
         */
        @Override
        public PageResult findPage(QueryPageBean queryPageBean)
            {
                //解析查询条件
                Map<String, Object> queryConditions = checkGroupServiceImpl.parseQueryConditions(queryPageBean.getQueryString());
                //log.info("查询条件map：{}", queryConditions);
                
                //设置分页参数
                PageHelper.startPage(queryPageBean.getCurrentPage(), queryPageBean.getPageSize());
                
                //开始查询
                List<Setmeal> setmealList = setmealMapper.query(queryConditions);
                //获取套餐关联的检查组信息
                for (Setmeal setmeal : setmealList)
                    {
                        BeanUtils.copyProperties(findById(setmeal.getId()), setmeal);
                    }
                
                //封装返回PageResult对象
                Page<Setmeal> page = (Page<Setmeal>) setmealList;
                return new PageResult(page.getTotal(), page.getResult());
            }
        
        /**
         * 删除由id
         *
         * @param setmealId 套餐id
         */
        @Override
        @Transactional
        public void deleteById(Integer setmealId)
            {
                //先删除套餐关联的图片，避免浪费空间
                HashMap<String, Object> queryHashMap = new HashMap<>();
                queryHashMap.put("setmealId", setmealId);
                //根据id查询到的只有一条数据，直接get(0)即可，然后调用方法删除
                List<Setmeal> setmealList = setmealMapper.query(queryHashMap);
                //获取图片信息
                String imgName = setmealList.get(0).getImg();
                String endpoint = aliOssProperties.getEndpoint();
                String bucketName = aliOssProperties.getBucketName();
                //对象中存储的是文件完整路径，把文件名前面的路径部分替换为空字符串得到的就是原图片名
                String picName = imgName.replace("https://" + bucketName + "." + endpoint + "/", "");
                
                //开始删除
                aliOssUtil.delete(picName);
                
                //删除套餐
                setmealMapper.deleteById(setmealId);
                //删除套餐与检查组的关联关系
                setmealCheckGroupMapper.deleteBySetmealId(setmealId);
                
                //删除静态页面
                deleteStaticPages();
            }
        
        /**
         * 插入中间表信息
         *
         * @param setmeal       套餐
         * @param checkGroupIds 检查组 ID
         */
        private void insertSetmealCheckGroup(Setmeal setmeal, List<Integer> checkGroupIds)
            {
                //先删除原本关联的检查组
                setmealCheckGroupMapper.deleteBySetmealId(setmeal.getId());
                Map<String, Integer> map = new HashMap<>();
                map.put("setmealId", setmeal.getId());
                //存入新的关联关系
                for (Integer checkGroupId : checkGroupIds)
                    {
                        map.put("checkGroupId", checkGroupId);
                        setmealCheckGroupMapper.insert(map);
                    }
            }
        
        /**
         * 删除静态页面
         */
        private void deleteStaticPages()
            {
                String specificFileName = "setmeal.html";
                String fileNamePart = "setmeal_detail_";
                
                File directory = new File(path);
                
                // 检查目录是否存在
                if (directory.exists() && directory.isDirectory())
                    {
                        File[] files = directory.listFiles();
                        if (files != null)
                            {
                                for (File file : files)
                                    {
                                        // 删除特定的文件
                                        if (file.isFile() && file.getName().equals(specificFileName))
                                            {
                                                boolean isDeleted = file.delete();
                                                if (isDeleted)
                                                    {
                                                        System.out.println("文件已被删除: " + file.getAbsolutePath());
                                                    }
                                                else
                                                    {
                                                        System.out.println("文件删除失败: " + file.getAbsolutePath());
                                                    }
                                            }
                                        // 删除包含特定字符串的文件
                                        else if (file.isFile() && file.getName().contains(fileNamePart))
                                            {
                                                boolean isDeleted = file.delete();
                                                if (isDeleted)
                                                    {
                                                        System.out.println("文件已被删除: " + file.getAbsolutePath());
                                                    }
                                                else
                                                    {
                                                        System.out.println("文件删除失败: " + file.getAbsolutePath());
                                                    }
                                            }
                                    }
                            }
                    }
                else
                    {
                        System.out.println("目录不存在: " + path);
                    }
            }
    }
